From d51fe548dd9a36994a19f455e250d6b199b2e788 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 16 Oct 2014 11:25:05 -0700 Subject: [PATCH] Split out encoding from `core::resolver` to a submodule Same exported hierarchy, just some internal orgainzational changes. --- src/cargo/core/resolver/encode.rs | 179 +++++++++++++++++ .../core/{resolver.rs => resolver/mod.rs} | 185 +----------------- 2 files changed, 189 insertions(+), 175 deletions(-) create mode 100644 src/cargo/core/resolver/encode.rs rename src/cargo/core/{resolver.rs => resolver/mod.rs} (80%) diff --git a/src/cargo/core/resolver/encode.rs b/src/cargo/core/resolver/encode.rs new file mode 100644 index 000000000..2eab82fe3 --- /dev/null +++ b/src/cargo/core/resolver/encode.rs @@ -0,0 +1,179 @@ +use std::collections::HashMap; + +use regex::Regex; +use serialize::{Encodable, Encoder, Decodable, Decoder}; + +use core::{PackageId, SourceId}; +use util::{CargoResult, Graph}; + +use super::Resolve; + +#[deriving(Encodable, Decodable, Show)] +pub struct EncodableResolve { + package: Option>, + root: EncodableDependency +} + +impl EncodableResolve { + pub fn to_resolve(&self, default: &SourceId) -> CargoResult { + let mut g = Graph::new(); + + try!(add_pkg_to_graph(&mut g, &self.root, default)); + + match self.package { + Some(ref packages) => { + for dep in packages.iter() { + try!(add_pkg_to_graph(&mut g, dep, default)); + } + } + None => {} + } + + let root = self.root.to_package_id(default); + Ok(Resolve { graph: g, root: try!(root), features: HashMap::new() }) + } +} + +fn add_pkg_to_graph(g: &mut Graph, + dep: &EncodableDependency, + default: &SourceId) + -> CargoResult<()> +{ + let package_id = try!(dep.to_package_id(default)); + g.add(package_id.clone(), []); + + match dep.dependencies { + Some(ref deps) => { + for edge in deps.iter() { + g.link(package_id.clone(), try!(edge.to_package_id(default))); + } + }, + _ => () + }; + + Ok(()) +} + +#[deriving(Encodable, Decodable, Show, PartialOrd, Ord, PartialEq, Eq)] +pub struct EncodableDependency { + name: String, + version: String, + source: Option, + dependencies: Option> +} + +impl EncodableDependency { + fn to_package_id(&self, default_source: &SourceId) -> CargoResult { + PackageId::new( + self.name.as_slice(), + self.version.as_slice(), + self.source.as_ref().unwrap_or(default_source)) + } +} + +#[deriving(Show, PartialOrd, Ord, PartialEq, Eq)] +pub struct EncodablePackageId { + name: String, + version: String, + source: Option +} + +impl> Encodable for EncodablePackageId { + fn encode(&self, s: &mut S) -> Result<(), E> { + let mut out = format!("{} {}", self.name, self.version); + if let Some(ref s) = self.source { + out.push_str(format!(" ({})", s.to_url()).as_slice()); + } + out.encode(s) + } +} + +impl> Decodable for EncodablePackageId { + fn decode(d: &mut D) -> Result { + let string: String = raw_try!(Decodable::decode(d)); + let regex = Regex::new(r"^([^ ]+) ([^ ]+)(?: \(([^\)]+)\))?$").unwrap(); + let captures = regex.captures(string.as_slice()) + .expect("invalid serialized PackageId"); + + let name = captures.at(1); + let version = captures.at(2); + + let source = captures.at(3); + + let source_id = if source == "" { + None + } else { + Some(SourceId::from_url(source.to_string())) + }; + + Ok(EncodablePackageId { + name: name.to_string(), + version: version.to_string(), + source: source_id + }) + } +} + +impl EncodablePackageId { + fn to_package_id(&self, default_source: &SourceId) -> CargoResult { + PackageId::new( + self.name.as_slice(), + self.version.as_slice(), + self.source.as_ref().unwrap_or(default_source)) + } +} + +impl> Encodable for Resolve { + fn encode(&self, s: &mut S) -> Result<(), E> { + let mut ids: Vec<&PackageId> = self.graph.iter().collect(); + ids.sort(); + + let encodable = ids.iter().filter_map(|&id| { + if self.root == *id { return None; } + + Some(encodable_resolve_node(id, &self.root, &self.graph)) + }).collect::>(); + + EncodableResolve { + package: Some(encodable), + root: encodable_resolve_node(&self.root, &self.root, &self.graph) + }.encode(s) + } +} + +fn encodable_resolve_node(id: &PackageId, root: &PackageId, + graph: &Graph) -> EncodableDependency { + let deps = graph.edges(id).map(|edge| { + let mut deps = edge.map(|e| { + encodable_package_id(e, root) + }).collect::>(); + deps.sort(); + deps + }); + + let source = if id.get_source_id() == root.get_source_id() { + None + } else { + Some(id.get_source_id().clone()) + }; + + EncodableDependency { + name: id.get_name().to_string(), + version: id.get_version().to_string(), + source: source, + dependencies: deps, + } +} + +fn encodable_package_id(id: &PackageId, root: &PackageId) -> EncodablePackageId { + let source = if id.get_source_id() == root.get_source_id() { + None + } else { + Some(id.get_source_id().clone()) + }; + EncodablePackageId { + name: id.get_name().to_string(), + version: id.get_version().to_string(), + source: source, + } +} diff --git a/src/cargo/core/resolver.rs b/src/cargo/core/resolver/mod.rs similarity index 80% rename from src/cargo/core/resolver.rs rename to src/cargo/core/resolver/mod.rs index 2e846e315..dbec2bf6b 100644 --- a/src/cargo/core/resolver.rs +++ b/src/cargo/core/resolver/mod.rs @@ -1,17 +1,21 @@ use std::collections::hashmap::{HashMap, HashSet, Occupied, Vacant}; use std::fmt; -use regex::Regex; -use semver; -use serialize::{Encodable, Encoder, Decodable, Decoder}; - use core::{PackageId, Registry, SourceId, Summary, Dependency}; use core::PackageIdSpec; use util::{CargoResult, Graph, human, internal, ChainError}; use util::profile; use util::graph::{Nodes, Edges}; -/// Result of the `resolve` function. +pub use self::encode::{EncodableResolve, EncodableDependency, EncodablePackageId}; + +mod encode; + +/// Represents a fully resolved package dependency graph. Each node in the graph +/// is a package and edges represent dependencies between packages. +/// +/// Each instance of `Resolve` also understands the full set of features used +/// for each package as well as what the root package is. #[deriving(PartialEq, Eq)] pub struct Resolve { graph: Graph, @@ -26,176 +30,6 @@ pub enum ResolveMethod<'a> { /* uses_default_features = */ bool), } -#[deriving(Encodable, Decodable, Show)] -pub struct EncodableResolve { - package: Option>, - root: EncodableDependency -} - -impl EncodableResolve { - pub fn to_resolve(&self, default: &SourceId) -> CargoResult { - let mut g = Graph::new(); - - try!(add_pkg_to_graph(&mut g, &self.root, default)); - - match self.package { - Some(ref packages) => { - for dep in packages.iter() { - try!(add_pkg_to_graph(&mut g, dep, default)); - } - } - None => {} - } - - let root = self.root.to_package_id(default); - Ok(Resolve { graph: g, root: try!(root), features: HashMap::new() }) - } -} - -fn add_pkg_to_graph(g: &mut Graph, - dep: &EncodableDependency, - default: &SourceId) - -> CargoResult<()> -{ - let package_id = try!(dep.to_package_id(default)); - g.add(package_id.clone(), []); - - match dep.dependencies { - Some(ref deps) => { - for edge in deps.iter() { - g.link(package_id.clone(), try!(edge.to_package_id(default))); - } - }, - _ => () - }; - - Ok(()) -} - -#[deriving(Encodable, Decodable, Show, PartialOrd, Ord, PartialEq, Eq)] -pub struct EncodableDependency { - name: String, - version: String, - source: Option, - dependencies: Option> -} - -impl EncodableDependency { - fn to_package_id(&self, default_source: &SourceId) -> CargoResult { - PackageId::new( - self.name.as_slice(), - self.version.as_slice(), - self.source.as_ref().unwrap_or(default_source)) - } -} - -#[deriving(Show, PartialOrd, Ord, PartialEq, Eq)] -pub struct EncodablePackageId { - name: String, - version: String, - source: Option -} - -impl> Encodable for EncodablePackageId { - fn encode(&self, s: &mut S) -> Result<(), E> { - let mut out = format!("{} {}", self.name, self.version); - if let Some(ref s) = self.source { - out.push_str(format!(" ({})", s.to_url()).as_slice()); - } - out.encode(s) - } -} - -impl> Decodable for EncodablePackageId { - fn decode(d: &mut D) -> Result { - let string: String = raw_try!(Decodable::decode(d)); - let regex = Regex::new(r"^([^ ]+) ([^ ]+)(?: \(([^\)]+)\))?$").unwrap(); - let captures = regex.captures(string.as_slice()) - .expect("invalid serialized PackageId"); - - let name = captures.at(1); - let version = captures.at(2); - - let source = captures.at(3); - - let source_id = if source == "" { - None - } else { - Some(SourceId::from_url(source.to_string())) - }; - - Ok(EncodablePackageId { - name: name.to_string(), - version: version.to_string(), - source: source_id - }) - } -} - -impl EncodablePackageId { - fn to_package_id(&self, default_source: &SourceId) -> CargoResult { - PackageId::new( - self.name.as_slice(), - self.version.as_slice(), - self.source.as_ref().unwrap_or(default_source)) - } -} - -impl> Encodable for Resolve { - fn encode(&self, s: &mut S) -> Result<(), E> { - let mut ids: Vec<&PackageId> = self.graph.iter().collect(); - ids.sort(); - - let encodable = ids.iter().filter_map(|&id| { - if self.root == *id { return None; } - - Some(encodable_resolve_node(id, &self.root, &self.graph)) - }).collect::>(); - - EncodableResolve { - package: Some(encodable), - root: encodable_resolve_node(&self.root, &self.root, &self.graph) - }.encode(s) - } -} - -fn encodable_resolve_node(id: &PackageId, root: &PackageId, - graph: &Graph) -> EncodableDependency { - let deps = graph.edges(id).map(|edge| { - let mut deps = edge.map(|e| { - encodable_package_id(e, root) - }).collect::>(); - deps.sort(); - deps - }); - - let source = if id.get_source_id() == root.get_source_id() { - None - } else { - Some(id.get_source_id().clone()) - }; - - EncodableDependency { - name: id.get_name().to_string(), - version: id.get_version().to_string(), - source: source, - dependencies: deps, - } -} - -fn encodable_package_id(id: &PackageId, root: &PackageId) -> EncodablePackageId { - let source = if id.get_source_id() == root.get_source_id() { - None - } else { - Some(id.get_source_id().clone()) - }; - EncodablePackageId { - name: id.get_name().to_string(), - version: id.get_version().to_string(), - source: source, - } -} - impl Resolve { fn new(root: PackageId) -> Resolve { let mut g = Graph::new(); @@ -739,3 +573,4 @@ mod test { assert_that(&res, contains(names(["root", "foo", "bar", "baz"]))); } } + -- 2.30.2